﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace G.Controls
{
    public class PageListService
    {
        public static readonly DependencyProperty PageListDataProperty = DependencyProperty.RegisterAttached("PageListData", typeof(PageListData), typeof(PageListService), new PropertyMetadata(null, OnPageListDataChanged));


        private static void OnPageListDataChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ListViewBase element = o as ListViewBase;
            var data = GetPageListData(element);
            if (data != null)
            {
                data.Initial(element);
            }
        }

        public static PageListData GetPageListData(ListViewBase element)
        {
            return element.GetValue(PageListDataProperty) as PageListData;
        }

        public static void SetPageListData(ListViewBase element, PageListData value)
        {
            element.SetValue(PageListDataProperty, value);
        }
    }


    public class PageListData : DependencyObject
    {
        public static readonly DependencyProperty PageSizeProperty = DependencyProperty.Register("PageSize", typeof(int), typeof(PageListData), new PropertyMetadata(20));
        /// <summary>
        /// 每页大小,默认是20
        /// </summary>
        public int PageSize
        {
            get
            {
                return (int)this.GetValue(PageSizeProperty);
            }
            set
            {
                this.SetValue(PageSizeProperty, value);
            }
        }

        private ListViewBase ListBox;
        internal void Initial(ListViewBase listbox)
        {
            ListBox = listbox;
            listbox.LayoutUpdated += listbox_LayoutUpdated;
        }

        void listbox_LayoutUpdated(object sender, object e)
        {
            if (ScrollViewer == null)
                ScrollViewer = this.ListBox.GetVisualDescendants<ScrollViewer>().FirstOrDefault();
            if (ScrollViewer != null)
            {
                ListBox.LayoutUpdated -= listbox_LayoutUpdated;
                if (ScrollViewer.GetHorizontalScrollBarVisibility(ListBox) == ScrollBarVisibility.Disabled)
                {
                    PropertyValueChangedNotify = new PropertyChangedNotify() { Path = new PropertyPath("VerticalOffset") };
                    PropertyChangedNotify.SetListener(ScrollViewer, PropertyValueChangedNotify);
                    PVCHandel = PageListData_PropertyValueChanged_VerticalOffiset;
                }
                else if (ScrollViewer.GetVerticalScrollBarVisibility(ListBox) == ScrollBarVisibility.Disabled)
                {
                    PropertyValueChangedNotify = new PropertyChangedNotify() { Path = new PropertyPath("HorizontalOffset") };
                    PropertyChangedNotify.SetListener(ScrollViewer, PropertyValueChangedNotify);
                    PVCHandel = PageListData_PropertyValueChanged_HorizontalOffset;
                }
                if (this.IsEnablePage)
                {
                    this.PropertyValueChangedNotify.PropertyValueChanged += this.PVCHandel;
                    PVCHandel(scrollViewer, null);
                    //this.LoadingData();
                }
            }
        }

        private PropertyValueChangedHandle PVCHandel;


        void PageListData_PropertyValueChanged_HorizontalOffset(DependencyObject d, PropertyValueChangedEventArgs e)
        {
            double diff = (ScrollViewer.ExtentWidth - ScrollViewer.HorizontalOffset - ScrollViewer.ViewportWidth);
            if (diff <= 0)
            {
                LoadingData();
            }
        }

        void PageListData_PropertyValueChanged_VerticalOffiset(DependencyObject d, PropertyValueChangedEventArgs e)
        {
            double diff = (ScrollViewer.ExtentHeight - ScrollViewer.VerticalOffset - ScrollViewer.ViewportHeight);
            //if (ScrollViewer.ScrollableHeight > 0 && diff < 1)
            //{
            //    LoadingData();
            //}

            if (diff <= 0)
            {
                LoadingData();
            }
        }
        public static readonly DependencyProperty IsEnablePageProperty = DependencyProperty.Register("IsEnablePage", typeof(bool), typeof(PageListData), new PropertyMetadata(false, IsEnablePagePropertyChanged));

        private static void IsEnablePagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PageListData data = d as PageListData;
            if (data.IsEnablePage)
            {
                if (data.PropertyValueChangedNotify != null)
                {
                    data.PropertyValueChangedNotify.PropertyValueChanged += data.PVCHandel;
                    data.LoadingData();
                }
            }
            else
            {
                data.PropertyValueChangedNotify.PropertyValueChanged -= data.PVCHandel;
            }
        }
        /// <summary>
        /// 是否启用分页
        /// </summary>
        public bool IsEnablePage
        {
            get
            {
                return (bool)this.GetValue(IsEnablePageProperty);
            }
            set
            {
                this.SetValue(IsEnablePageProperty, value);
            }
        }

        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(PageListData), null);
        public ICommand Command
        {
            get
            {
                return this.GetValue(CommandProperty) as ICommand;
            }
            set
            {
                this.SetValue(CommandProperty, value);
            }
        }

        public event PageEventHandle BeginLoadData;

        private ScrollViewer scrollViewer;

        internal ScrollViewer ScrollViewer
        {
            get { return scrollViewer; }
            set { scrollViewer = value; }
        }
        PropertyChangedNotify PropertyValueChangedNotify;


        /// <summary>
        /// 当前页
        /// </summary>
        public int CurrentPage { get; set; }
        private bool IsLoading;
        private void LoadingData()
        {
            if (!IsLoading)
            {
                PageEventArgs e = new PageEventArgs();
                IsLoading = true;
                e.IsLoadedChangedCallBack = (s) =>
                {
                    this.IsLoading = false;
                };
                e.PageSize = this.PageSize;
                e.PageNum = ++CurrentPage;
                if (Command != null)
                    Command.Execute(e);
                else if (BeginLoadData != null)
                    BeginLoadData(this, e);
            }
        }
    }

    public delegate void PageEventHandle(object sender, PageEventArgs e);
    //public delegate void PageListBoxLoadDataHandle<T>(IEnumerable<T> datas);
    public class PageEventArgs : EventArgs
    {
        internal Action<bool> IsLoadedChangedCallBack;
        public int PageNum { get; internal set; }
        public int PageSize { get; internal set; }
        private bool isLoaded;
        /// <summary>
        /// 是否启用分页
        /// </summary>
        public bool IsLoaded
        {
            get
            {
                return isLoaded;
            }
            set
            {
                if (isLoaded != value)
                {
                    isLoaded = value;
                    if (IsLoadedChangedCallBack != null)
                        IsLoadedChangedCallBack(value);
                }
            }
        }
    }
}
